package com.rerun.common.shiro;

import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.rerun.entity.SysUser;
import com.rerun.service.ISysRoleMenuService;
import com.rerun.service.ISysUserRoleService;
import com.rerun.service.ISysUserService;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.cache.Cache;
import org.apache.shiro.crypto.hash.SimpleHash;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.subject.SimplePrincipalCollection;
import org.apache.shiro.util.ByteSource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.annotation.Resource;
import java.util.Set;

/**
 * shiro Realm
 *
 * @author jameszhou
 */
public class MyRealm extends AuthorizingRealm {
	Logger logger = LoggerFactory.getLogger(getClass());
    /**
     * 用户服务
     */
    @Resource
    private ISysUserService userService;
    /**
     * 用户角色服务
     */
    @Resource
    private ISysUserRoleService sysUserRoleService;
    /**
     * 角色菜单服务
     */
    @Resource
    private ISysRoleMenuService sysRoleMenuService;

    /**
     * 认证
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {


        UsernamePasswordToken user = (UsernamePasswordToken) token;
        SysUser sysUser = userService.selectOne(new EntityWrapper<SysUser>().eq("userName", user.getUsername()));

        if (sysUser == null) {
            throw new UnknownAccountException();
        }
        if (sysUser.getUserState() == SysUser._0) {
            throw new LockedAccountException();
        }
        //用户名，数据库中的密码,reaml名称
        //SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(user.getUsername(),sysUser.getPassword(),getName());
        //盐值加密
        ByteSource byteSource = ByteSource.Util.bytes(user.getUsername());
        return new SimpleAuthenticationInfo(sysUser, sysUser.getPassword(), byteSource, getName());
    }


    /**
     * 授权
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
        // TODO Auto-generated method stub

        SysUser sysUser = (SysUser) principals.getPrimaryPrincipal();
        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
        Set<String> roles = sysUserRoleService.findRolesByUid(sysUser.getId());
        Set<String> permissions = sysRoleMenuService.findMenusByUid(sysUser.getId());
        info.setRoles(roles);
        info.setStringPermissions(permissions);
        return info;
    }


    /**
     * 密码加密 测试
     *
     * @param args the input arguments
     */
    public static void main(String[] args) {
        // MD5,"原密码","盐",加密次数
        String pwd = new SimpleHash("MD5", "123456", "admin", 1024).toString();
        System.out.println(pwd);

    }
    
    @Override
    protected void clearCachedAuthenticationInfo(PrincipalCollection principals) {
        Cache c = getAuthenticationCache();
        super.clearCachedAuthenticationInfo(principals);
        // 添加下面的代码清空【认证】的缓存
        SysUser user = (SysUser) principals.getPrimaryPrincipal();
        SimplePrincipalCollection spc = new SimplePrincipalCollection(user.getUserName(),getName());
        super.clearCachedAuthenticationInfo(spc);
        int cacheSize = c.keys().size();
        if (cacheSize == 0){
            logger.info("【认证】缓存被清空了。");
        }
    }

    @Override
    protected void clearCachedAuthorizationInfo(PrincipalCollection principals) {
        super.clearCachedAuthorizationInfo(principals);
    }
}
